#include<iostream>
#include<string>
#include<vector>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<thread>

using namespace std;


//c++线程
void threadrun( int num)
{
    while(num)
    {
        std::cout << name << " num : " << num<< std::endl;
        num--;
        sleep(1);
    }
}
int main()
{
    std::string name = "thread-1";
    std::thread mythread(threadrun, 10);

    while(true)
    {
        std::cout << "main thhread..." << std::endl;
        sleep(1);
    }

    mythread.join();
    return 0;
}












//可以给线程传递多个参数
// class ThreadData
// {
//     public:
//     string name;
//     string num;
//     int x;
//     int y;
//     //......
// };

// class ThreadResult
// {
//     public:
//     int x;
//     int y;
//     int result;
// };
// //5.全面看待线程函数返回：a.只考虑正确的返回，不考虑异常，因为异常了整个进程就崩溃了，包括主线程也就崩溃了
// //b.可以传递任意类型，包括类对象的地址
// void* threadRun(void* args)
// {
//     //string name = (const char*)args;//传参
//     //int a = *(int*)args;
//     ThreadData *td = static_cast<ThreadData*>(args);
//     int cnt=10;
//     while(cnt)
//     {
//         //cout<<name<<" run ,cnt:"<<cnt--<<endl;
//         //cout<<a<<" run ,cnt:"<<cnt--<<endl;
//         cout<<td->name<<" run ,cnt:"<<cnt--<<"num"<<td->num<<endl;
//         sleep(1);
//     }
//     return nullptr;
//     //return (void*)111;
// }

// string printThHex(pthread_t &tid)
// {
//     char buffer[64];
//      snprintf(buffer, sizeof(buffer), "0x%lx", tid);
//      return buffer;
// }


void* threadrun(void* args)//创建多线程需要的新线程函数
{
    //pthread_detach(pthread_self());//线程分离
    string name = static_cast<const char*>(args);
    while(true)
    {
        cout<<name<<" is runing"<<endl;
        sleep(1);
    }
    //return args;
    //exit(1)专门用来终止进程的，不能用来终止线程
    pthread_exit(args);
}
const int num=10;

//main函数结束，main thread结束，表示进程也就结束
int main()//线程的创建和等待
{
    //7.新线程的终止
    //(1)函数return
    //（2）pthread_exit()专门一个终止线程
    //（3）int pthread_cancel(pthread_t thread)取消线程前提是线程要存在，返回结果是-1


    //8.可以不可以不join线程，让他执行完就退出呢？？可以
    //线程分离int pthread_detach(pthread_t thread)
    //// a. 一个线程被创建，默认是joinable的，必须要被join的.
     // b. 如果一个线程被分离，线程的工作状态分离状态，不须要/不能被join的. 依旧属于进程内部，但是不需要被等待了



    // vector<pthread_t> tids;
    // //6.创建多线程
    // for(int i=0;i<num;i++)
    // {
    //     //1.线程的id
    //     pthread_t tid;
    //     //2.线程的name
    //     char *name= new char[128];
    //     snprintf(name,128,"thread-%d",i+1);
    //     pthread_create(&tid,nullptr,threadrun,/*线程的名字*/name);
    //     //3.保存所有信息的id
    //     tids.emplace_back(tid);
    // }
    
    //主线程主动分离
    // for(auto tid:tids)
    // {
    //     pthread_detach(tid);//主线程分离新线程，新线程必须存在

    // }



    // //创建多线程的等待
    // for(auto tid:tids)
    // {
    //    pthread_cancel(tid);//取消线程
    //   cout<<"cancel thread"
        //void* result = nullptr;
        //pthread_join(tid,&result);//线程被取消的后果是-1

    //     void* name = nullptr;
    //     pthread_join(tid,&name);
    // }


    // pthread_t tid;//unsigned long int类型
    // //1.main和new线程谁先运行不确定

    // //4.全面看待线程传参:可以传递任意类型，也可以传递类对象的地址
    // int a = 100;

    // // ThreadData td;//此时新线程可以访问主线程的栈；相当于是共享的，不推荐
    // // td.name = "thread ";
    // // td.num = 1;
    // //推荐以下做法
    // ThreadData *td = new ThreadData();//此时新线程可以访问主线程的栈；相当于是共享的，不推荐
    // td->name = "thread ";
    // td->num = 1;

    // //int n = pthread_create(&tid,nullptr,threadRun,(void*)"thread 1");
    // //int n = pthread_create(&tid,nullptr,threadRun,(void*)&a);
    // //int n = pthread_create(&tid,nullptr,threadRun,(void*)&td);
    // int n = pthread_create(&tid,nullptr,threadRun,td);
    // if(n!=0)
    // {
    //     cerr<<"create new thread error"<<endl;
    //     return 1;
    // }

    // //3.tid是虚拟地址
    // string tid_str = printThHex(tid);//按照16进制打印出来
    // cout<<"tid:"<<tid_str<<endl;

    // cout<<"thread join begin"<<endl;
    // //2.希望main线程先退出

    // //void* code = nullptr;//有空间；void*看成一个整体相当是int类型
    // //n=pthread_join(tid,&code);//线程等待；  参数传递是从新线程中传递过来的

    // n=pthread_join(tid,nullptr);//线程等待；  如果不等待就会类似进程的僵尸状态
    // if(n==0)
    // {
    //     cout<<"main thread wait success"<<endl;
    // }
    return 0;
}